package com.ymt.bpm.service.platform.profile.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.ymt.bpm.appboot.BpmpProperties;
import com.ymt.bpm.appboot.env.Caches;
import com.ymt.bpm.dao.MDao;
import com.ymt.bpm.dao.Mapper;
import com.ymt.bpm.engine.EngineConst;
import com.ymt.bpm.model.PTenant;
import com.ymt.bpm.model.PUser;
import com.ymt.bpm.model.PUserExt;
import com.ymt.bpm.service.platform.cache.CacheService;
import com.ymt.bpm.service.platform.fauth.FaResService;
import com.ymt.bpm.service.platform.profile.UserProfileService;
import com.ymt.bpm.util.DateUtil;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by Johnny on 2017/1/30.
 */
@Service
@EnableConfigurationProperties(BpmpProperties.class)
public class UserProfileServiceImpl implements UserProfileService {

    @Resource
    private MDao dao;

    @Autowired
    private BpmpProperties bpmp;

    @Autowired
    private FaResService rs;

    @Autowired
    private CacheService cacheService;

    @Override
    //@CacheEvict(value= Caches.USER, key = "#user.userId")
    public JSONObject update(String lsn, String ldn, PUser user, String oldPwd) {
        JSONObject rtn = new JSONObject();

        int rs = dao.update("PUserMapper", "updateByPrimaryKeySelective", user);
        rtn.put("result", rs);

        cacheService.remove(Caches.USER, user.getUserId());

        return rtn;
    }

    @Override
    @Transactional(EngineConst.TRANSACTION_MANAGER)
    //@CacheEvict(value= Caches.USER, key = "#userExt.userId")
    public JSONObject updateExt(String lsn, String ldn, PUserExt userExt) {
        JSONObject rtn = new JSONObject();

        PUserExt userExtOld = dao.selectOne("PUserExtMapper", "selectByPrimaryKey", userExt.getUserId());

        Date now = DateUtil.getGMTDate();
        userExt.setUpdateTime(now);
        userExt.setUpdator(lsn);
        userExt.setUpdatorName(ldn);

        int rs = 0;
        if (userExtOld!=null) {
            rs = dao.update("PUserExtMapper", "updateByPrimaryKeySelective", userExt);
        } else {
            PUser user = dao.selectOne("PUserMapper", "selectByPrimaryKey", userExt.getUserId());
            userExt.setTenantId(user.getTenantId());
            userExt.setCreateTime(now);
            userExt.setCreator(lsn);
            userExt.setCreatorName(ldn);
            rs = dao.insert("PUserExtMapper", "insertSelective", userExt);
        }

        cacheService.remove(Caches.USER, lsn);

        rtn.put("result", rs);
        return rtn;
    }

    @Override
    //@CacheEvict(value= Caches.USER, key = "#userId")
    public JSONObject delete(String lsn, String ldn, String userId) {
        int rs = dao.delete("PUserMapper", "deleteByPrimaryKey", userId);
        JSONObject rtn = new JSONObject();
        rtn.put("result", rs);

        cacheService.remove(Caches.USER, userId);

        return rtn;
    }

    @Override
    // @CacheEvict(value= Caches.USER, key = "#lsn")
    public JSONObject changePwd(String lsn, String ldn, String newPwd, String oldPwd) {
        JSONObject rtn = new JSONObject();
        PUser user = dao.selectOne("PUserMapper", "selectByPrimaryKey", lsn);
        if (!user.getPassword().equals(DigestUtils.sha256Hex(oldPwd))) {
            rtn.put("errorCode", "WRONG_OLD_PWD");
            return rtn;
        }
        user.setPassword(DigestUtils.sha256Hex(newPwd));
        int rs = dao.update("PUserMapper", "updateByPrimaryKeySelective", user);
        rtn.put("result", rs);

        cacheService.remove(Caches.USER, lsn);

        return rtn;
    }

    @Override
    //@Cacheable(value=Caches.USERRIGHTS, key="'getUserAdminMenu_'+#tenantId+'_'+#loginName")
    public JSONArray getUserAdminMenu(String tenantId, String loginName) {

        String cacheKey = cacheService.asKey(Caches.UserRightsPrefix.MENUS_ADMIN.name(), tenantId, loginName);
        JSONArray rtn = cacheService.get(Caches.USERRIGHTS, cacheKey);

        if (rtn==null) {
            PUser user = dao.selectOne("PUserMapper", "selectByPrimaryKey", loginName);

            //判断是否是超管或租户管理员
            boolean isSuperVisor = loginName.equalsIgnoreCase(bpmp.getSupervisor());
            boolean isAdmin = false;

            if (user.getTenantId()!=null) {
                PTenant tenant = dao.selectOne(Mapper.PTenantMapper, "selectByPrimaryKey", user.getTenantId());
                if (user.getLoginName().equalsIgnoreCase(tenant.getAdmin())) {
                    isAdmin = true;
                }
            }
            if (isSuperVisor) {  //读取所有
                rtn = rs.getSuperVisorAdminMenu();
            } else if (isAdmin) {   //读取所有
                rtn = rs.getAllAdminMenu(tenantId);
            } else {        //根据授权读取
                rtn = rs.getUserAdminMenu(tenantId, loginName);
            }

            if (rtn!=null) {
                cacheService.put(Caches.USERRIGHTS, cacheKey, rtn);
            }
        }

        return rtn;
    }

    @Override
    //@Cacheable(value=Caches.USERRIGHTS, key="'getUserPortalMenu_'+#tenantId+'_'+#loginName")
    public JSONObject getUserPortalMenu(String tenantId, String loginName) {

        String cacheKey = cacheService.asKey(Caches.UserRightsPrefix.MENUS_PORTAL.name(), tenantId, loginName);
        JSONObject rtn = cacheService.get(Caches.USERRIGHTS, cacheKey);

        if (rtn==null) {
            PUser user = dao.selectOne("PUserMapper", "selectByPrimaryKey", loginName);
            //判断是否是超管或租户管理员
            boolean isSuperVisor = loginName.equalsIgnoreCase(bpmp.getSupervisor());
            boolean isAdmin = false;

            if (user.getTenantId()!=null) {
                PTenant tenant = dao.selectOne(Mapper.PTenantMapper, "selectByPrimaryKey", user.getTenantId());
                if (user.getLoginName().equalsIgnoreCase(tenant.getAdmin())) {
                    isAdmin = true;
                }
            }
            //根据授权读取
            rtn = rs.getUserPortalMenu(tenantId, loginName);
            if (isSuperVisor || isAdmin) {  //set isAdmin true
                rtn.put("isAdmin", true);
            }

            if (rtn!=null) {
                cacheService.put(Caches.USERRIGHTS, cacheKey, rtn);
            }
        }

        return rtn;
    }

}
